1 module core.stdc.math;
2 import core.stdc.stddef;
3 static import std.math.constants;
4 enum float PI = std.math.constants.PI;
5 enum float PI_2 = std.math.constants.PI_2;
6 enum float PI_4 = std.math.constants.PI_4;
7 
8 version(WebAssembly)
9 {
10     @nogc nothrow @safe pure
11     {
12         extern(C)
13         {
14 
15             //Double
16             double sqrt(double x){return cast(double)sqrtf(cast(float)x);}
17             double atan2(double y, double x){return cast(double)atan2f(cast(float)y, cast(float)x);}
18             double cos(double x){return cast(double)cosf(cast(float)x);}
19             double acos(double x){return cast(double)acosf(cast(float)x);}
20             double sin(double x){return cast(double)sinf(cast(float)x);}
21             double tan(double x){return cast(double)tanf(cast(float)x);}
22             double cbrt(double x);
23 
24 
25 
26             double fabs(double x){ return (x != x) ? x :  (x > 0 ? x : -x);}
27             double pow(double x, double y)
28             {
29                 long n = cast(long)y;
30                 if(n == 0) return 1;
31                 double ret = x;
32 
33                 if(n > 0) foreach(i; 1..n)
34                     ret*=x;
35                 else if(x == 0)
36                     return double.infinity;
37                 else foreach(i; y..1)
38                     ret/= x;
39                 return ret;
40             }
41             float powf(float x, float y){return cast(float)core.stdc.math.pow(cast(double)x, cast(double)y);}
42 
43             double floor(double x){return cast(long)(x-0.99999999);}
44             double ceil(double x){return cast(double)(cast(long)(x+0.999999999));}
45             double fmod(double f, double w)
46             {
47                 auto i = cast(int) f;
48                 return i % cast(int) w;
49             }
50 
51 
52             //Float
53             float sqrtf(float x);
54             float atan2f(float y, float x) { return fastAtan2(y, x);}
55             float cosf(float x){ return fastCos(x); }
56             float acosf(float x) { return fastAcos(x); }
57             float sinf(float x) { return fastSin(x); }
58             float tanf(float x) { return fastTan(x); }
59 
60             float fabsf(float x){return (x != x) ? x :  (x > 0 ? x : -x);}
61             float floorf(float x){return cast(float)(cast(int)x);}
62             float ceilf(float x){return cast(float)(cast(int)(x+0.999999999));}
63             float fmodf(float x, float denom)
64             {
65                 float div = x / denom;
66                 div = div - cast(int)div;
67                 return cast(float)(cast(int)div*denom);
68             }
69         }
70 
71 
72         immutable float[256] sineTable = [
73             0f, 0.00615995f, 0.0123197f, 0.0184789f, 0.0246374f, 0.0307951f, 0.0369515f, 0.0431065f, 0.0492599f, 0.0554115f,
74             0.0615609f, 0.067708f, 0.0738525f, 0.0799943f, 0.0861329f, 0.0922684f, 0.0984003f, 0.104528f, 0.110653f, 0.116773f,
75             0.122888f, 0.128999f, 0.135105f, 0.141206f, 0.147302f, 0.153392f, 0.159476f, 0.165554f, 0.171626f, 0.177691f,
76             0.18375f, 0.189801f, 0.195846f, 0.201882f, 0.207912f, 0.213933f, 0.219946f, 0.225951f, 0.231948f, 0.237935f,
77             0.243914f, 0.249883f, 0.255843f, 0.261793f, 0.267733f, 0.273663f, 0.279583f, 0.285492f, 0.29139f, 0.297277f,
78             0.303153f, 0.309017f, 0.31487f, 0.32071f, 0.326539f, 0.332355f, 0.338158f, 0.343949f, 0.349727f, 0.355491f,
79             0.361242f, 0.366979f, 0.372702f, 0.378411f, 0.384106f, 0.389786f, 0.395451f, 0.401102f, 0.406737f, 0.412357f,
80             0.417961f, 0.423549f, 0.429121f, 0.434677f, 0.440216f, 0.445739f, 0.451244f, 0.456733f, 0.462204f, 0.467658f,
81             0.473094f, 0.478512f, 0.483912f, 0.489293f, 0.494656f, 0.5f, 0.505325f, 0.510631f, 0.515918f, 0.521185f,
82             0.526432f, 0.53166f, 0.536867f, 0.542053f, 0.54722f, 0.552365f, 0.557489f, 0.562593f, 0.567675f, 0.572735f,
83             0.577774f, 0.58279f, 0.587785f, 0.592757f, 0.597707f, 0.602634f, 0.607539f, 0.61242f, 0.617278f, 0.622113f,
84             0.626924f, 0.631711f, 0.636474f, 0.641213f, 0.645928f, 0.650618f, 0.655283f, 0.659924f, 0.66454f, 0.66913f,
85             0.673695f, 0.678235f, 0.682748f, 0.687236f, 0.691698f, 0.696133f, 0.700543f, 0.704925f, 0.709281f, 0.71361f,
86             0.717911f, 0.722186f, 0.726433f, 0.730653f, 0.734844f, 0.739008f, 0.743144f, 0.747252f, 0.751331f, 0.755382f,
87             0.759404f, 0.763398f, 0.767362f, 0.771297f, 0.775203f, 0.77908f, 0.782927f, 0.786744f, 0.790532f, 0.794289f,
88             0.798016f, 0.801713f, 0.80538f, 0.809016f, 0.812622f, 0.816196f, 0.81974f, 0.823252f, 0.826733f, 0.830183f,
89             0.833602f, 0.836988f, 0.840343f, 0.843666f, 0.846957f, 0.850216f, 0.853443f, 0.856637f, 0.859799f, 0.862928f,
90             0.866025f, 0.869088f, 0.872119f, 0.875116f, 0.878081f, 0.881012f, 0.883909f, 0.886773f, 0.889603f, 0.8924f,
91             0.895163f, 0.897892f, 0.900586f, 0.903247f, 0.905873f, 0.908465f, 0.911022f, 0.913545f, 0.916033f, 0.918487f,
92             0.920905f, 0.923289f, 0.925637f, 0.927951f, 0.930229f, 0.932472f, 0.93468f, 0.936852f, 0.938988f, 0.941089f,
93             0.943154f, 0.945184f, 0.947177f, 0.949135f, 0.951056f, 0.952942f, 0.954791f, 0.956604f, 0.958381f, 0.960122f,
94             0.961826f, 0.963493f, 0.965124f, 0.966718f, 0.968276f, 0.969797f, 0.971281f, 0.972728f, 0.974139f, 0.975512f,
95             0.976848f, 0.978148f, 0.97941f, 0.980635f, 0.981823f, 0.982973f, 0.984086f, 0.985162f, 0.986201f, 0.987202f,
96             0.988166f, 0.989092f, 0.98998f, 0.990831f, 0.991645f, 0.992421f, 0.993159f, 0.993859f, 0.994522f, 0.995147f,
97             0.995734f, 0.996284f, 0.996795f, 0.997269f, 0.997705f, 0.998103f, 0.998464f, 0.998786f, 0.999071f, 0.999317f,
98             0.999526f, 0.999696f, 0.999829f, 0.999924f, 0.999981f, 1.0f
99         ];
100 
101         float fastSin(float radians)
102         {
103             import std.math.constants;
104 
105             enum PI_3 = PI_2+PI;
106             radians = radians - cast(int)(radians / (2 * PI)) * (2 * PI);
107 
108             float factor = sineTable.length / (PI / 2);
109             int index = cast(int)(radians * factor) % sineTable.length;
110             if (radians < PI_2) return sineTable[index];
111             if (radians < PI) return sineTable[sineTable.length - index - 1];
112             if (radians < PI_3) return -sineTable[index];
113             return -sineTable[sineTable.length - index - 1];
114         }
115         float fastCos(float radians)
116         {
117             import std.math.constants;
118             return fastSin(radians + PI_2);
119         }
120         float fastTan(float radians){return fastSin(radians) / fastCos(radians);}
121         double fastAtan(float x)
122         {
123             // Efficient aproximation for arctan
124             enum double B = 0.28125; // ~9/32
125 
126             bool neg = false;
127             if (x < 0) {
128                 x = -x;
129                 neg = true;
130             }
131 
132             double result;
133             if (x < 1.0) {
134                 result = x / (1 + B * x * x);
135             } else {
136                 result = PI / 2 - (1 / x) / (1 + B / (x * x));
137             }
138 
139             return neg ? -result : result;
140         }
141 
142         float fastAsin(float x)
143         {
144             enum tolerance=1e-6;
145             ///Compute arcsin(x) using Taylor series expansion.
146             if(x < -1 || x > 1)
147                 return float.nan;
148 
149             float result = x;
150             float term = x;
151             int n = 1;
152             while(fabsf(term) > tolerance)
153             {
154                 term *= (x * x) * (2 * n - 1) ^^ 2 / ((2 * n) * (2 * n + 1));
155                 result += term;
156                 n += 1;
157             }
158 
159             return result;
160         }
161         float fastAcos(float x)
162         {
163             return PI_2 - fastAcos(x);
164         }
165 
166 
167         float fastAtan2(float y, float x) {
168             if (x == 0)
169                 return (y > 0) ? PI / 2 : 3 * PI / 2; // 90|270
170 
171             float atanVal = fastAtan(y / x);
172 
173             if (x < 0)
174                 atanVal += (y >= 0) ? PI : -PI;
175 
176             if (atanVal < 0)
177                 atanVal += 2 * PI;
178 
179             return atanVal;
180         }
181     }
182 }
183 else
184 {
185     extern(C) extern @nogc @safe nothrow pure
186     {
187         double sqrt(double x);
188         double atan2(double y, double x);
189         double cos(double x);
190         double acos(double x);
191         double sin(double x);
192         double tan(double x);
193         double fabs(double x);
194         double pow(double x, double y);
195         double floor(double x);
196         double ceil(double x);
197         double fmod(double x, double denom);
198         double cbrt(double x);
199         float cbrtf(float x);
200 
201 
202         float sqrtf(float x);
203         float atan2f(float y, float x);
204         float cosf(float x);
205         float acosf(float x);
206         float sinf(float x);
207         float tanf(float x);
208         float fabsf(float x);
209         float powf(float x, float y);
210         real powl(real x, real y);
211         float floorf(float x);
212         float ceilf(float x);
213         float fmodf(float x, float denom);
214 
215 
216         double exp(double x);
217         float expf(float x);
218 
219         double log(double x);
220         float logf(float x);
221         pure double  round(double x);
222         pure float   roundf(float x);
223 
224         float ldexpf(float n, int exp);   /* intrinsic */
225         double ldexp(double n, int exp); /* intrinsic */ /// ditto
226         real ldexpl(real n, int exp);     /* intrinsic */ /// ditto
227     }
228 }
229 
230 extern(C) @nogc nothrow @trusted pure:
231 
232 enum int FP_ILOGB0        = int.min;
233 ///
234 enum int FP_ILOGBNAN      = int.min;
235 // extern(D) real fmodl()(real x, real y) { return fmod(cast(double) x, cast(double) y); }
236 
237 // float remainderf( float x, float y ){assert(0);}
238 // double remainder( double x, double y ){assert(0);}
239 // real remainderl( real x, real y ){assert(0);}
240 // double  remquo(double x, double y, int* quo){assert(0);}
241 // float   remquof(float x, float y, int* quo){assert(0);}
242 // extern(D) real remquol()(real x, real y, int* quo) { return remquo(cast(double) x, cast(double) y, quo); }
243 // extern(D) pure real cbrtl()(real x)   { return cbrt(cast(double) x); }
244 // extern(D) pure real modfl()(real value, real* iptr)
245 // {
246 //     double i;
247 //     double r = modf(cast(double) value, &i);
248 //     *iptr = i;
249 //     return r;
250 // }
251 
252 // pure double  modf(double value, double* iptr){assert(0);}
253 // pure float   modff(float value, float* iptr){assert(0);}
254 // extern(C) pure double  nearbyint(double x){assert(0);}
255 // // pure float   nearbyintf(float x){assert(0);}
256 // // extern(D) pure real nearbyintl()(real x) { return nearbyint(cast(double) x); }
257 
258 // pure float   roundf(float x)
259 // {
260 //     return ((x - cast(int)x) >= 0.5) ? cast(int)x+1 : cast(int)x;
261 // }
262 // pure double  round(double x){ return cast(double)roundf(x);}
263 // extern(D) pure real roundl()(real x)  { return round(cast(double) x); }
264 
265 // long llround(double x)
266 // {
267 //     return ((x - cast(long)x) >= 0.5) ? cast(long)x+1 : cast(long)x;
268 // }
269 //     ///
270 // long llroundf(float x){return llroundf(cast(double)x);}
271 // ///
272 // extern(C) long llroundl(double x) { return llround(cast(double) x); }
273 // extern(D) long llroundl()(real x) { return llround(cast(double) x); }
274 
275 
276 // pure double  trunc(double x) {return cast(double)(cast(long)x);}
277 // ///
278 // pure float   truncf(float x) {return cast(float)(cast(int)x);}
279 // ///
280 // extern(D) pure real truncl()(real x)  { return trunc(cast(double) x); }
281 
282 
283 
284 
285 // ///////////////////////////////////////Comparisons///////////////////////////////////////
286 
287 // ///real1 > real2
288 // extern(C) bool __gttf2(real a  , real b){assert(false);}
289 // ///real1 < real2
290 // extern(C) bool __lttf2(real a, real b){assert(false);}
291 // ///real <= real2
292 // extern(C) bool __letf2(real a, real b){assert(false);}
293 // ///real != real
294 // extern(C) real __netf2(real a, real b){assert(false);}
295 // /// real == real
296 // extern(C) real __eqtf2(real a, real b){assert(false);}
297 // ///isNaN(real)
298 // extern(C) bool __unordtf2(real a, real b){assert(false);}
299 // ///comp float a and b
300 // extern(C) bool __getf2(float a, float b){assert(false);}
301 
302 
303 // ///////////////////////////////////////Basic Operations///////////////////////////////////////
304 
305 // ///real + real
306 // extern(C) real __addtf3(real a, real b){assert(false);}
307 // ///real - real
308 // extern(C) real __subtf3(real a, real b){assert(false);}
309 // ///real / real
310 // extern(C) real __divtf3(real a, real b){assert(false);}
311 // ///real * real
312 // extern(C) real __multf3(real a, real b){assert(false);}
313 
314 
315 
316 
317 // ///////////////////////////////////////Special Operations///////////////////////////////////////
318 
319 // /// round(real)
320 // extern(C) real rintl(real a){assert(false);}
321 // ///cos(real)
322 // extern(C) real cosl(real a){assert(false);}
323 // ///sqrt(real)
324 // extern(C) real sqrtl(real a){assert(false);}
325 // ///sin(real)
326 // extern(C) real sinl(real a){assert(false);}
327 
328 // ///////////////////////////////////////Castings///////////////////////////////////////
329 
330 // // ///cast(double)realValue
331 // extern(C) double __trunctfdf2(real x){assert(false);}
332 // ///cast(float)real
333 // extern(C) float __trunctfsf2(real a){assert(false);}
334 // ///cast(real)uint
335 // extern(C) real __floatunsitf (uint a){assert(false);}
336 // ///cast(real)long
337 // extern(C) real __floatditf(long a){assert(false);}
338 // ///cast(real)ulong
339 // extern(C) real __floatunditf(long a){assert(false);}
340 // ///cast(real) double
341 // extern(C) real __extenddftf2(double a){assert(false);}
342 // ///cast(real) float
343 // extern(C) real __extendsftf2(float a){assert(false);}
344 // ///cast(real)long
345 // extern(C) real __fixtfdi(long a){assert(false);}
346 // ///cast(real)int
347 // extern(C) real __floatsitf(int a){assert(false);}
348 // ///Don't know
349 // extern(C) int __fixtfsi(float a){assert(false);}